package com.edu.hre.struts.action.recruit;

import java.awt.Image;
import java.io.ByteArrayInputStream;
import java.util.Date;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;

import com.edu.hre.common.utils.BeanFinder;
import com.edu.hre.common.utils.ComboBoxInit;
import com.edu.hre.common.utils.CommonUtils;
import com.edu.hre.common.utils.StringConstants;
import com.edu.hre.db.pojo.HreJobCandidate;
import com.edu.hre.db.pojo.HreJobCandidateAttachment;
import com.edu.hre.db.pojo.HreJobCandidatePicture;
import com.edu.hre.db.service.BaseService;
import com.edu.hre.db.utils.Compare;
import com.edu.hre.struts.form.recruit.CandidateUpdateForm;

public class CandidateUpdateAction extends Action {

	private static final Logger logger = Logger.getLogger(CandidateUpdateAction.class);
	private static final BaseService baseService = BeanFinder.getBean(BaseService.BEAN_NAME, BaseService.class);
	private final String ACTION_NAME = "candidateUpdate";
	
	public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		CommonUtils.println(CommonUtils.getSourceCodeLocation());
		CandidateUpdateForm beanForm = (CandidateUpdateForm) form;
		beanForm.setIsAddNew(false);
		
		if(request.getParameter("btnUpdate") == null){

			int id = CommonUtils.getIntParameter("id", request);
			CandidateUpdateAction.setAttributesForRequest(id, request);

			HreJobCandidate tmp = baseService.getFirstPojo("id", Compare.EQUAL, id, null, null, 0, HreJobCandidate.class);

			if (tmp == null) {
				initFormBean(beanForm, request);
				beanForm.setMessage(StringConstants.BLANK);
				beanForm.setSuccess(false);
				return mapping.findForward(ACTION_NAME);
			}
			
			beanForm.setId(tmp.getId());
			beanForm.setFirstName(CommonUtils.normalizeString(tmp.getFirstName()));
			beanForm.setMiddleName(CommonUtils.normalizeString(tmp.getMiddleName()));
			beanForm.setLastName(CommonUtils.normalizeString(tmp.getLastName()));
			beanForm.setEmail(CommonUtils.normalizeString(tmp.getEmail()));
			beanForm.setContactNumber(CommonUtils.normalizeString(tmp.getContactNumber()));
			beanForm.setIdCardNumber(CommonUtils.normalizeString(tmp.getIdCardNumber()));
			beanForm.setIdCardLocationIssued(CommonUtils.normalizeString(tmp.getIdCardLocationIssued()));
			beanForm.setIdCardDateIssued(CommonUtils.dateToString(tmp.getIdCardDateIssued()));
			beanForm.setGender(tmp.getGender() == null ? 0 : tmp.getGender());
			beanForm.setMaritalStatus(CommonUtils.normalizeString(tmp.getMaritalStatus()));
			beanForm.setNationality(tmp.getNationality() == null ? 0 : tmp.getNationality());
			beanForm.setDateOfBirth(CommonUtils.dateToString(tmp.getEmpBirthday()));
			beanForm.setAddressStreet(CommonUtils.normalizeString(tmp.getAddress()));
			beanForm.setDistrictCode(CommonUtils.normalizeString(tmp.getDistrictCode()));
			beanForm.setProvinceCode(CommonUtils.normalizeString(tmp.getProvinCode()));

			initFormBean(beanForm, request);
			beanForm.setMessage(StringConstants.BLANK);
			beanForm.setSuccess(false);
			return mapping.findForward(ACTION_NAME);
		}
		
		CandidateUpdateAction.setAttributesForRequest(beanForm.getId(), request);
		
		String message = validateForm(beanForm);
		if(!StringUtils.isBlank(message)){
			beanForm.setMessage(message);
			initFormBean(beanForm, request);
			beanForm.setSuccess(false);
			return mapping.findForward(ACTION_NAME);
		}

		HreJobCandidate tmp = baseService.getFirstPojo("id", Compare.EQUAL, beanForm.getId(), null, null, 0, HreJobCandidate.class);
		if (tmp == null) {
			initFormBean(beanForm, request);
			beanForm.setMessage(StringConstants.BLANK);
			beanForm.setSuccess(false);
			return mapping.findForward(ACTION_NAME);
		}

		tmp.setFirstName(CommonUtils.normalizeString(beanForm.getFirstName()));
		tmp.setMiddleName(CommonUtils.normalizeString(beanForm.getMiddleName()));
		tmp.setLastName(CommonUtils.normalizeString(beanForm.getLastName()));
		tmp.setEmail(CommonUtils.normalizeString(beanForm.getEmail()));
		tmp.setContactNumber(CommonUtils.normalizeString(beanForm.getContactNumber()));
		tmp.setIdCardNumber(CommonUtils.normalizeString(beanForm.getIdCardNumber()));
		tmp.setIdCardLocationIssued(CommonUtils.normalizeString(beanForm.getIdCardLocationIssued()));
		tmp.setIdCardDateIssued(CommonUtils.stringToDate(beanForm.getIdCardDateIssued()));
		tmp.setGender(beanForm.getGender());
		tmp.setMaritalStatus(CommonUtils.normalizeString(beanForm.getMaritalStatus()));
		tmp.setNationality(beanForm.getNationality());
		tmp.setEmpBirthday(CommonUtils.stringToDate(beanForm.getDateOfBirth()));
		tmp.setAddress(CommonUtils.normalizeString(beanForm.getAddressStreet()));
		tmp.setDistrictCode(CommonUtils.normalizeString(beanForm.getDistrictCode()));
		tmp.setProvinCode(CommonUtils.normalizeString(beanForm.getProvinceCode()));
		tmp.setDateModified(new Date());

		boolean status = baseService.saveOrUpdate(tmp);
		if (!status) {
			beanForm.setMessage(StringConstants.UPDATE_FAILURE_MESSAGE);
			initFormBean(beanForm, request);
			beanForm.setSuccess(false);
			return mapping.findForward(ACTION_NAME);
		}

		FormFile imageFile = beanForm.getImage();
		if(imageFile != null && StringUtils.isNotBlank(imageFile.getFileName())){
			HreJobCandidatePicture picture = baseService.getFirstPojo("candidateId", Compare.EQUAL, tmp.getId(), null, null, 0, HreJobCandidatePicture.class);
			if(picture == null){
				picture = new HreJobCandidatePicture();
			}
			picture.setCanFileType(imageFile.getContentType());
			picture.setCandidateId(tmp.getId());
			picture.setCanFileSize(String.valueOf(imageFile.getFileSize()));
			picture.setDateModified(new Date());
			picture.setDateCreated(new Date());
			picture.setCanFileName(imageFile.getFileName());
			picture.setCanPicture(imageFile.getFileData());

			String w = null;
			String h = null;
			try {
				Image imgTemp = ImageIO.read(new ByteArrayInputStream(imageFile.getFileData()));
				w = imgTemp.getWidth(null) + StringConstants.BLANK;
				h = imgTemp.getHeight(null) + StringConstants.BLANK;				
			} catch (Exception e) {
				CommonUtils.println(e.getMessage());
			}
			picture.setCanFileWidth(w);
			picture.setCanFileHeight(h);
			baseService.saveOrUpdate(picture);
		}
		
		// Insert or Update CV file
		FormFile cvFile = beanForm.getCvFile();
		if(cvFile != null && StringUtils.isNotBlank(cvFile.getFileName())){
			HreJobCandidateAttachment attach = baseService.getFirstPojo("candidateId", Compare.EQUAL, tmp.getId(), null, null, 0, HreJobCandidateAttachment.class);
			if(attach == null){
				attach = new HreJobCandidateAttachment();
			}
			attach.setFileType(cvFile.getContentType());
			attach.setCandidateId(tmp.getId());
			attach.setFileSize(cvFile.getFileSize());
			attach.setDateModified(new Date());
			attach.setDateCreated(new Date());
			attach.setFileName(cvFile.getFileName());
			attach.setFileContent(cvFile.getFileData());

			baseService.saveOrUpdate(attach);
		}

		CandidateUpdateAction.setAttributesForRequest(beanForm.getId(), request);
		beanForm.setMessage("Candidate personal details have been updated successfully!");
		beanForm.setSuccess(true);
		return mapping.findForward(ACTION_NAME);
	}

	private void initFormBean(CandidateUpdateForm beanForm, HttpServletRequest request) {

		beanForm.setAllDistricts(ComboBoxInit.getAllDistricts(true));
		beanForm.setAllProvinces(ComboBoxInit.getAllProvinces(true));
		beanForm.setAllMaritalStatuses(ComboBoxInit.getAllMaritalStatuses());
		beanForm.setAllNationalities(ComboBoxInit.getAllNationalities(true));
		beanForm.setAllGenders(ComboBoxInit.getAllGenders(true));
	}

	public static void setAttributesForRequest (int candidateId, HttpServletRequest request) {
		
		HreJobCandidate tmp = baseService.getFirstPojo("id", Compare.EQUAL, candidateId, null, null, 0, HreJobCandidate.class);
		
		request.setAttribute("can_id", candidateId);
		
		if (tmp == null) {
			request.setAttribute("can_fullname", "Not Available");
			return;
		}

		request.setAttribute("can_fullname", tmp.getLastName() + " " + tmp.getMiddleName() + " " + tmp.getFirstName());
	}

	private String validateForm (CandidateUpdateForm beanForm) {
		
		if(StringUtils.isBlank(CommonUtils.normalizeString(beanForm.getFirstName()))){
			return "First name cannot be blank!";
		}

		if(StringUtils.isBlank(CommonUtils.normalizeString(beanForm.getLastName()))){
			return "Last name cannot be blank!";
		}
		
		if (CommonUtils.checkLaterThanToday(beanForm.getIdCardDateIssued(), -1, -1, -1)) {
			return "Issued date of the ID card must not be in the future!";
		}
		
		if (CommonUtils.checkLaterThanToday(beanForm.getDateOfBirth(), -1, -1, -1)) {
			return "Date of birth must not be in the future!";
		}

		FormFile imageFile = beanForm.getImage();
		if(imageFile != null && StringUtils.isNotBlank(imageFile.getFileName())){
			if(imageFile.getFileSize() > 2097152){
				return "Image file size is too big! (< 2MB required)";
			} else if(!"image/jpeg".equalsIgnoreCase(imageFile.getContentType())){
				return "Invalid file type! Only JPEG or PNG files are accepted!";
			}
		}

		FormFile cvFile = beanForm.getCvFile();
		if(cvFile != null && StringUtils.isNotBlank(cvFile.getFileName())){
			if(cvFile.getFileSize() > 10485760){
				return "CV file size is too large! (< 10 MB required!)";
			} else if(!"application/pdf".equalsIgnoreCase(cvFile.getContentType())
					&& !"application/msword".equalsIgnoreCase(cvFile.getContentType())
					&& !"application/vnd.openxmlformats-officedocument.wordprocessingml.document".equalsIgnoreCase(cvFile.getContentType())){
				return "CV file type is not valid! (Only .pdf, .doc or .docx files are accepted!)";
			}
		}

		return StringConstants.BLANK;
	}
}
